/**
 * 共通工具函数
 */

import { ElMessage } from 'element-plus'
import { ref } from 'vue'

// 全局日志管理
const globalLogs = ref<Array<{ timestamp: Date; level: 'info' | 'warn' | 'error' | 'success'; message: string }>>([])

// 仿真状态常量
export const SIMULATION_STATUS = {
  WAITING: 'waiting',
  RUNNING: 'running',
  COMPLETED: 'completed',
  ERROR: 'error',
  CANCELLED: 'cancelled'
} as const

export const STATUS_TYPES = {
  waiting: 'info',
  running: 'warning',
  completed: 'success',
  error: 'danger',
  cancelled: 'info'
} as const

// 日志工具
export const logUtils = {
  // 添加日志
  addLog: (level: 'info' | 'warn' | 'error' | 'success', message: string) => {
    globalLogs.value.unshift({
      timestamp: new Date(),
      level,
      message
    })
    if (globalLogs.value.length > 100) {
      globalLogs.value = globalLogs.value.slice(0, 100)
    }
  },
  
  // 清空日志
  clearLogs: () => {
    globalLogs.value = []
  },
  
  // 获取日志
  getLogs: () => globalLogs.value
}

// 格式化时间
export const formatTime = (date: Date | string | number): string => {
  const d = new Date(date)
  return d.toLocaleString('zh-CN', {
    year: 'numeric',
    month: '2-digit',
    day: '2-digit',
    hour: '2-digit',
    minute: '2-digit',
    second: '2-digit'
  })
}

// 格式化文件大小
export const formatFileSize = (bytes: number): string => {
  if (bytes === 0) return '0 B'
  
  const k = 1024
  const sizes = ['B', 'KB', 'MB', 'GB', 'TB']
  const i = Math.floor(Math.log(bytes) / Math.log(k))
  
  return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i]
}

// 防抖函数
export const debounce = <T extends (...args: any[]) => any>(
  func: T,
  wait: number
): ((...args: Parameters<T>) => void) => {
  let timeout: number | null = null
  
  return (...args: Parameters<T>) => {
    if (timeout) clearTimeout(timeout)
    timeout = setTimeout(() => func(...args), wait)
  }
}

// 节流函数
export const throttle = <T extends (...args: any[]) => any>(
  func: T,
  wait: number
): ((...args: Parameters<T>) => void) => {
  let lastTime = 0
  
  return (...args: Parameters<T>) => {
    const now = Date.now()
    if (now - lastTime >= wait) {
      lastTime = now
      func(...args)
    }
  }
}

// 深拷贝
export const deepClone = <T>(obj: T): T => {
  if (obj === null || typeof obj !== 'object') return obj
  if (obj instanceof Date) return new Date(obj.getTime()) as unknown as T
  if (obj instanceof Array) return obj.map(item => deepClone(item)) as unknown as T
  if (typeof obj === 'object') {
    const clonedObj = {} as T
    for (const key in obj) {
      if (obj.hasOwnProperty(key)) {
        clonedObj[key] = deepClone(obj[key])
      }
    }
    return clonedObj
  }
  return obj
}

// 生成唯一ID
export const generateId = (): string => {
  return Date.now().toString(36) + Math.random().toString(36).substr(2)
}

// 验证邮箱
export const validateEmail = (email: string): boolean => {
  const re = /^[^\s@]+@[^\s@]+\.[^\s@]+$/
  return re.test(email)
}

// 验证手机号
export const validatePhone = (phone: string): boolean => {
  const re = /^1[3-9]\d{9}$/
  return re.test(phone)
}

// 数字格式化
export const formatNumber = (num: number, decimals: number = 2): string => {
  return num.toLocaleString('zh-CN', {
    minimumFractionDigits: decimals,
    maximumFractionDigits: decimals
  })
}

// 颜色工具
export const hexToRgb = (hex: string): { r: number; g: number; b: number } | null => {
  const result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex)
  return result ? {
    r: parseInt(result[1]!, 16),
    g: parseInt(result[2]!, 16),
    b: parseInt(result[3]!, 16)
  } : null
}

// 获取文件扩展名
export const getFileExtension = (filename: string): string => {
  return filename.slice((filename.lastIndexOf('.') - 1 >>> 0) + 2)
}

// 检查是否为图片文件
export const isImageFile = (filename: string): boolean => {
  const imageExtensions = ['jpg', 'jpeg', 'png', 'gif', 'bmp', 'webp', 'svg']
  const ext = getFileExtension(filename).toLowerCase()
  return imageExtensions.includes(ext)
}

// 检查是否为视频文件
export const isVideoFile = (filename: string): boolean => {
  const videoExtensions = ['mp4', 'avi', 'mov', 'wmv', 'flv', 'webm', 'mkv']
  const ext = getFileExtension(filename).toLowerCase()
  return videoExtensions.includes(ext)
}

// 检查是否为音频文件
export const isAudioFile = (filename: string): boolean => {
  const audioExtensions = ['mp3', 'wav', 'flac', 'aac', 'ogg', 'wma']
  const ext = getFileExtension(filename).toLowerCase()
  return audioExtensions.includes(ext)
}

// 数组去重
export const uniqueArray = <T>(array: T[], key?: keyof T): T[] => {
  if (!key) {
    return [...new Set(array)]
  }
  
  const seen = new Set()
  return array.filter(item => {
    const value = item[key]
    if (seen.has(value)) {
      return false
    }
    seen.add(value)
    return true
  })
}

// 数组分组
export const groupBy = <T>(array: T[], key: keyof T): Record<string, T[]> => {
  return array.reduce((groups, item) => {
    const value = String(item[key])
    if (!groups[value]) {
      groups[value] = []
    }
    groups[value].push(item)
    return groups
  }, {} as Record<string, T[]>)
}

// 等待指定时间
export const sleep = (ms: number): Promise<void> => {
  return new Promise(resolve => setTimeout(resolve, ms))
}

// 重试函数
export const retry = async <T>(
  fn: () => Promise<T>,
  maxAttempts: number = 3,
  delay: number = 1000
): Promise<T> => {
  let lastError: Error
  
  for (let attempt = 1; attempt <= maxAttempts; attempt++) {
    try {
      return await fn()
    } catch (error) {
      lastError = error as Error
      if (attempt < maxAttempts) {
        await sleep(delay * attempt)
      }
    }
  }
  
  throw lastError!
}

// 消息提示工具函数
export const showMessage = {
  success: (message: string) => ElMessage.success(message),
  error: (message: string) => ElMessage.error(message),
  warning: (message: string) => ElMessage.warning(message),
  info: (message: string) => ElMessage.info(message)
}

// 确认对话框
export const showConfirm = async (message: string, title: string = '确认'): Promise<boolean> => {
  const { ElMessageBox } = await import('element-plus')
  try {
    await ElMessageBox.confirm(message, title, {
      type: 'warning'
    })
    return true
  } catch {
    return false
  }
}

// 文件操作相关工具
export const fileUtils = {
  // 复制到剪贴板
  copyToClipboard: async (text: string): Promise<boolean> => {
    try {
      await navigator.clipboard.writeText(text)
      return true
    } catch {
      return false
    }
  },
  
  // 获取文件扩展名
  getExtension: (filename: string): string => {
    return getFileExtension(filename)
  },
  
  // 检查文件类型
  isImage: (filename: string): boolean => isImageFile(filename),
  isVideo: (filename: string): boolean => isVideoFile(filename),
  isAudio: (filename: string): boolean => isAudioFile(filename)
}
